package com.activitiFlow.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.activitiFlow.service.IHistoryBiz;
import com.activitiFlow.service.IRuntimeBiz;
import com.activitiFlow.service.ITaskBiz;
import com.vx.FlowCode;
import com.vx.service.IProcessInstanceEntryService;

@Service("taskBiz")
public class TaskBizImpl implements ITaskBiz {
	
	@Autowired
	private IHistoryBiz historyBiz;

	@Autowired
	private TaskService taskService;
	
	@Autowired
	private IProcessInstanceEntryService processInstanceEntryService;
	
	@Autowired
	private RuntimeService runtimeService;
	
	@Override
	public Task getTaskByTaskId(String taskId) {
		return taskService.createTaskQuery().taskId(taskId).singleResult();
	}
	

	@Override
	public List<Task> getRunTaskListByUserCode(String userCode) {
		List<Task> taskList=new ArrayList<Task>();
		taskList.addAll(taskService.createTaskQuery().taskAssignee(userCode).orderByTaskCreateTime().desc().list());
		//查询用户组下的用户参与办理的任务
		taskList.addAll(taskService.createTaskQuery().taskCandidateUser(userCode).orderByTaskCreateTime().desc().list());
		return taskList;
	}

	@Override
	public void addComment(String taskId, String processInstanceId,String message) {
		taskService.addComment(taskId, processInstanceId, message);
	}
	
	@Override
	public void saveSubmitTask(String taskId, Map<String, Object> variables) {
		if(variables==null){
			taskService.complete(taskId);
		}else{
			taskService.complete(taskId, variables);
		}
	}
	

	@Override
	public void setAssigne(String taskId,String assigne) {
		taskService.delegateTask(taskId, assigne);
	}
	
	@Override
	public Task getTaskByTaskProcessInstanceId(String processInstanceId) {
		return taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
	}

	@Override
	public void claim(String taskId, String userCode) {
		taskService.claim(taskId, userCode);
	}
	
	
	@Override
	public void deleteCandidateUser(String taskId,String userCode){
		taskService.deleteCandidateUser(taskId, userCode);
	}
	
	
	@Override
	public void addCandidateUser(String taskId,String userCode){
		taskService.addCandidateUser(taskId,userCode);
	}

	@Override
	public String getVariable(String taskId, String variableName) {
		String varible=(String) taskService.getVariable(taskId, variableName);
//		runtimeService.getVariable(executionId, variableName);
		return varible;
	}


	@Override
	public List<Comment> getHistCommentByBorrowIdAndBuinessKey(String borrowId,String flowKey) {
		HistoricProcessInstance historyPI=historyBiz.queryHistoryProcessInstance(flowKey+"."+borrowId);
		return this.getHistCommentByProcessInstanceId(historyPI.getId());
	}


	@Override
	public List<Comment> getHistCommentByTaskId(String taskId) {
		return this.getHistCommentByProcessInstanceId(this.getTaskByTaskId(taskId).getProcessInstanceId());
	}
	
	
	private List<Comment> getHistCommentByProcessInstanceId(String processInstanceId) {
		
		List<Comment> list=new ArrayList<Comment>();
		//通过流程实例id找到历史流程任务，根据历史任务id 查询历史的办理信息
//		List<HistoricTaskInstance>  historicTask=historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).list();
//		if(historicTask!=null && historicTask.size()>0){
//			for (HistoricTaskInstance historicTaskInstance : historicTask) {
//				String hTaskId=historicTaskInstance.getId();
//				List<Comment> tasklist=taskService.getTaskComments(hTaskId);
//				list.addAll(tasklist);
//			}
//		}
		//根据流程实例id 查询历史的审批信息
		list=taskService.getProcessInstanceComments(processInstanceId);
		return list;
	}
	

	@Override
	public int submitTask(String userCode,String taskId, String outcome,String message,String _candidateUsers) {
		/**
		 * 1：在完成之前，添加一个批注信息，向act_hi_comment表中添加数据，用于记录对当前申请人的一些审核信息
		 */
		//使用任务ID，查询任务对象，获取流程流程实例ID
		Task task=this.getTaskByTaskId(taskId);
		//获取流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		/**
		 * 注意：添加批注的时候，由于Activiti底层代码是使用：
		 * 		String userId = Authentication.getAuthenticatedUserId();
			    CommentEntity comment = new CommentEntity();
			    comment.setUserId(userId);
			  所有需要从Session中获取当前登录人，作为该任务的办理人（审核人），对应act_hi_comment表中的User_ID的字段，不过不添加审核人，该字段为null
			 所以要求，添加配置执行使用Authentication.setAuthenticatedUserId();添加当前任务的审核人
		 * */
		Authentication.setAuthenticatedUserId(userCode);
		this.claim(taskId,userCode);
		this.addComment(taskId, processInstanceId, message);
		/**
		 * 2：如果连线的名称是“默认提交”，那么就不需要设置，如果不是，就需要设置流程变量
		 * 在完成任务之前，设置流程变量，按照连线的名称，去完成任务
				 流程变量的名称：outcome
				 流程变量的值：连线的名称
		 */
		Map<String, Object> variables = new HashMap<String,Object>();
		if(outcome!=null && !outcome.equals("默认提交")){
			variables.put("outcome", outcome);
		}
		//3：使用任务ID，完成当前人的个人任务，同时流程变量
		this.saveSubmitTask(taskId, variables);
		/**
		 * 5：在完成任务之后，判断流程是否结束
   			如果流程结束了，更新请假单表的状态从1变成2（审核中-->审核完成）
		 */
		ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		//流程结束了
		if(pi==null){
			return FlowCode.FLOW_END;
		}else{
			//4：当任务完成之后，需要指定下一个任务的办理人（使用类）
			//根据正在执行的流程对象的activtiId，去历史环节表act_hi_taskinst中查询是否有多条记录，如果有多条记录说明走的时驳回环节，添加上次的处理人
			ProcessInstance processInstance=runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
			String activiId=processInstance.getActivityId();
			List<HistoricTaskInstance> historyTaskList=historyBiz.queryHistoryTask(processInstanceId,activiId);
			String nextLeaderCode=null;
			if(historyTaskList.size()>1){
				HistoricTaskInstance historicTaskInstance=historyTaskList.get(0);
				String assigne=historicTaskInstance.getAssignee();
				nextLeaderCode=assigne;
				Task newTask=this.getTaskByTaskProcessInstanceId(processInstanceId);
				this.setAssigne(newTask.getId(),nextLeaderCode);
			}else{
				//判断流程中的办理人时何种设置方式：类监听 或者 通过流程变量设置
				Task newTask=this.getTaskByTaskProcessInstanceId(processInstanceId);
				ActivityImpl activityNode=processInstanceEntryService.getRunActivityNode(newTask.getId());
				Set userexpressionSet=((UserTaskActivityBehavior)activityNode.getActivityBehavior()).getTaskDefinition().getCandidateUserIdExpressions();
				if(userexpressionSet!=null && userexpressionSet.size()>0){
					if(_candidateUsers!=null){
						String[] candidateUserStr=StringUtils.split(_candidateUsers, ",");
						for (int i = 0; i < candidateUserStr.length; i++) {
							this.addCandidateUser(newTask.getId(),candidateUserStr[i]);
						}
					}
					this.deleteCandidateUser(newTask.getId(),userCode);
					this.deleteCandidateUser(newTask.getId(),this.getVariable(newTask.getId(), FlowCode.USERCODE));
				}
			}
			return FlowCode.FLOW_START;
		}
	}
	
}
